package com.oa.service.user.impl;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oa.aop.AspectException;
import com.oa.mapper.MyBaseMapper;
import com.oa.mapper.user.AttendCountMapper;
import com.oa.mapper.user.AttendanceMapper;
import com.oa.mapper.user.EmpMappper;
import com.oa.mapper.user.UserMapper;
import com.oa.pojo.Attendance;
import com.oa.pojo.AttendanceCount;
import com.oa.pojo.Emp;
import com.oa.service.user.AttendanceService;
import com.oa.vo.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author 朱晓萌
 */
@Service
@Slf4j
public class AttendanceImpl implements AttendanceService {
    @Autowired
    private AttendanceMapper attendanceMapper;

    @Autowired
    private EmpMappper empMappper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AttendCountMapper attendCountMapper;

    @Override
    public List<Attendance> getAttendanceList() {
        return attendanceMapper.selectList(null);
    }

    /**
     * 实现员工出勤表的增加
     */
    @Override
    public void setAttendanceStatus(Attendance attendance) {
        attendance.setAttendanceTime(new Date());
        String s = attendance.getEmpId().toString();
        String today = DateUtil.today();
        String index = s.concat(today);
        attendance.setAttendanceIndex(index);
        attendanceMapper.update(attendance, new UpdateWrapper<Attendance>().eq("Attendance_index", attendance.getAttendanceIndex()));

    }

    /**
     * 生成下班的时间
     * @param attendance
     */
    @Override
    public void setCloseStatus(Attendance attendance) {
        String attendanceIndex = attendance.getAttendanceIndex();
        //设置下班时间
        attendance.setCloseTime(new Date()).setOvertimeHours("系统统计中,请明日查询").setWorkTime("系统统计中,请明日查询").setAttendanceStatus("系统统计中,请明日查询");
//        System.out.println(attendance);
        //实现出勤状态的修改
        UpdateWrapper<Attendance> UpdateWrapper = new UpdateWrapper<>();
        UpdateWrapper.eq("Attendance_index", attendanceIndex);
        attendanceMapper.update(attendance, UpdateWrapper);
    }

    @Override
    public Attendance getAttendanceByIndex(String index) {
        return attendanceMapper.selectOne(new QueryWrapper<Attendance>().eq("Attendance_index", index));

    }

    /**
     * 定义出勤状态方法
     *
     * @param attendance
     */
    void attendanceStatusDefine(Attendance attendance) {
        String attendanceIndex = attendance.getAttendanceIndex();
        AttendanceCount attendanceCount = new AttendanceCount();
        String late = "迟到";
        String early = "早退";
        String overtime = "加班";
        String leak = "出勤时间不足";
        String normal = "正常出勤";
        String abnormal = "异常出勤";
        String nodata = "考勤记录不全";
        //定义员工id
        Integer empId = attendance.getEmpId();
        //定义日期
        DateTime dateTime = DateUtil.parse(attendance.getAttendanceIndex().substring(8), "yyyy-MM-dd");
        attendanceCount.setEmpId(empId).setAttendanceDay(dateTime);
        Date attendanceTime = attendance.getAttendanceTime();
        Date closeTime = attendance.getCloseTime();
        if (attendanceTime == null || closeTime == null) {
            attendance.setAttendanceStatus(StrUtil.format("{} {}", abnormal, nodata));
            attendance.setOvertimeHours("今日无加班!");
            attendance.setWorkTime("工作时间异常!");
            attendanceCount.setAbsentNum(1);
            attendanceCount.setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }

        //定义上班时间
        Date startTime = DateUtil.parse(DateUtil.today() + " 08:30");
        //定义下班时间
        Date endTime = DateUtil.parse(DateUtil.today() + " 17:30");
        //定义按分钟计算的加班时间
        //
        long workTimeByMin = DateUtil.between(attendanceTime, closeTime, DateUnit.MINUTE);
        String workTime = DateUtil.formatBetween(attendanceTime, closeTime, BetweenFormatter.Level.MINUTE);
        //定义加班的返回语句
        String template = StrUtil.format("您今天加班了{}分钟", StrUtil.toString(workTimeByMin - 480L));
        String overtimeHours = workTimeByMin >= 540L ? template : "您今天未达到加班时长(1hour),请继续加油哦!";
        //插入工作时间
        attendance.setWorkTime(workTime);
        //插入加班对应字段
        attendance.setOvertimeHours(overtimeHours);
        //定义出勤是否足够
        boolean workTimeFlag = workTimeByMin > 480L;
        //定义是否达到加班要求
        boolean overTimeFlag = workTimeByMin >= 540L;
        //定义是否迟到
        boolean lateFlag = attendanceTime.after(startTime);
        //定义是否早退
        boolean earlyFlag = closeTime.before(endTime);

        //正常出勤状态(未加班)
        if (!lateFlag && !earlyFlag && workTimeFlag && !overTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{}", normal));
            attendanceCount.setAttendanceNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //正常出勤状态(加班)
        if (!lateFlag && !earlyFlag && workTimeFlag && overTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {}", normal, overtime));
            attendanceCount.setAttendanceNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //异常出勤状态(迟到,早退)
        if (lateFlag && earlyFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {} {} {}", abnormal, leak, late, early));
            attendanceCount.setAbsentNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //异常出勤状态(迟到,出勤时间足够,但未加班)
        if (lateFlag && !earlyFlag && workTimeFlag && !overTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {}", abnormal, late));
            attendanceCount.setAbsentNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //异常出勤状态(迟到,出勤时间足够,加班)
        if (lateFlag && !earlyFlag && workTimeFlag && overTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {} {}", abnormal, late, overtime));
            attendanceCount.setAbsentNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //异常出勤状态(迟到,出勤时间不足)
        if (lateFlag && !earlyFlag && !workTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {} {}", abnormal, late, leak));
            attendanceCount.setAbsentNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //异常出勤状态(早退,出勤时间足够,但未加班)
        if (earlyFlag && !lateFlag && workTimeFlag && !overTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {}", abnormal, early));
            attendanceCount.setAbsentNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //异常出勤状态(早退,出勤时间足够,加班)
        if (earlyFlag && !lateFlag && workTimeFlag && overTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {} {}", abnormal, early, overtime));
            attendanceCount.setAbsentNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
            return;
        }
        //异常出勤状态(早退,出勤时间不足)
        if (earlyFlag && !lateFlag && !workTimeFlag) {
            attendance.setAttendanceStatus(StrUtil.format("{} {} {}", abnormal, early, leak));
            attendanceCount.setAbsentNum(1).setAttendanceIndex(attendanceIndex);
            attendCountMapper.insert(attendanceCount);
        }
    }


    /**
     * 生成所有员工每日的考勤记录(只包含index)
     */
    @Override
    @AspectException
    public List<Emp> mkAttendanceList() {

        //生成当天时间
        String today = DateUtil.today();
//        String today = "2021-10-25";
        //获取当日已生成的考勤表
//        List<Attendance> allAttendanceList = getAllAttendanceListByday(today);
//        ArrayList<Integer> ids = new ArrayList<>();
////        获取id列表
//        for (Attendance attendance : allAttendanceList) {
//            ids.add(attendance.getId());
//        }
//        //如果有数据就删除
//        if (!ids.isEmpty()) {
//            attendanceMapper.deleteBatchIds(ids);
//        }
        ArrayList<Attendance> attendances = new ArrayList<>();
        List<Emp> emps = empMappper.selectList(null);
        for (Emp emp : emps) {
            attendances.add(new Attendance().
                    setAttendanceIndex(emp.getEmpId() + today).
                    setEmpId(Integer.parseInt(emp.getEmpId())).setId(null)
                    .setAttendanceTime(null).setCloseTime(null).setOvertimeHours(" ").setWorkTime(" ").setAttendanceStatus(" "));
        }
        attendanceMapper.mysqlInsertAllBatch(attendances);
        return emps;
    }


    /**
     * 查询当日所有人的打卡记录
     *
     * @param
     * @return
     */
    @Override
    public PageResult getAllAttendanceList(PageResult pageResult) {
        String day=pageResult.getDate();
        Page<Attendance> page = new Page<>(pageResult.getPageNum(), pageResult.getPageSize());
        ArrayList<String> empIds = new ArrayList<>();
        List<Emp> emps = empMappper.selectList(null);
        HashMap<String, String> emplist = new HashMap<>();
        for (Emp emp : emps) {
            empIds.add(emp.getEmpId() + day);
            emplist.put(emp.getEmpId(), emp.getEmpName());
        }
        page = attendanceMapper.selectPage(page, new QueryWrapper<Attendance>().in("Attendance_index", empIds));
        List<Attendance> attendances = page.getRecords();
        for (Attendance attendance : attendances) {
            attendance.setEmpName(emplist.get(StrUtil.toString(attendance.getEmpId())));
        }
        pageResult.setRows(page.getRecords()).setTotal(page.getTotal());
        return pageResult;
    }
    @Override
    public List<Attendance> getAllAttendanceListByday(String day) {
        ArrayList<String> empIds = new ArrayList<>();
        List<Emp> emps = empMappper.selectList(null);
        HashMap<String, String> emplist = new HashMap<>();
        for (Emp emp : emps) {
            empIds.add(emp.getEmpId() + day);
            emplist.put(emp.getEmpId(), emp.getEmpName());
        }
        List<Attendance> attendances =
                attendanceMapper.selectList(new QueryWrapper<Attendance>().in("Attendance_index", empIds));
        for (Attendance attendance : attendances) {
            attendance.setEmpName(emplist.get(StrUtil.toString(attendance.getEmpId())));
        }
        return attendances;
    }

    /**
     * 实现考勤记录的批量状态生成
     * @param day
     */
    @Override
    public void dogenerateAttendanceStatus(String day) {
        List<Attendance> allAttendanceList = getAllAttendanceListByday(day);
        for (Attendance attendance : allAttendanceList) {
            attendanceStatusDefine(attendance);
            attendanceMapper.updateById(attendance);
//            log.info("attendance:{}", attendance);
        }
//        attendanceMapper.updateAttendanceList(allAttendanceList);

    }


}
